package com.qianya.system.filter;

import com.qianya.model.common.JWTUtil;
import com.qianya.model.pojo.login.vo.LoginRoleVO;
import com.qianya.model.pojo.login.vo.LoginUsersPermissionVO;
import com.qianya.system.config.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Package: com.qianya.system.filter
 * @ClassName: AuthFilter
 * @Author: zzq
 * @Description:
 * @Date: 2020/7/14 9:50
 * @Version: 1.0
 */
@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Value("${outUrl}")
    private String outUrl;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求的地址
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String requestUrl = request.getPath().toString();
//        if(regular(outUrl,requestUrl)){
//            return chain.filter(exchange);
//        }

        int result1 = requestUrl.indexOf("/statics");
        if (result1==0){
            return chain.filter(exchange);
        }
       String[] urlArray = outUrl.split(",");
        //如果这个请求在需放行的url中，直接放行
        for (String str:urlArray) {
            if(str.equals(requestUrl)){
                return chain.filter(exchange);
            }
        }
        List<String> list = request.getHeaders().get("token");
        //判断token
        HttpHeaders httpHeaders = response.getHeaders();
        httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
        if(list==null||list.size()==0){
           return response.writeWith(Flux.just(exception(exchange,"Token不能为空")));
        }
        String token = list.get(0);
        String userName = JWTUtil.getUsername(token);
        if(userName==null||!JWTUtil.verify(token,userName)){
            return response.writeWith(Flux.just(exception(exchange,"Token认证失败")));
        }
        //判断这个用户是否管理员,管理员直接放行
        if(JWTUtil.getUserType(token)==0){
            //放行
            return chain.filter(exchange);
        }
        //通过用户id从redis中获取权限
        Object redisUrl = RedisUtil.hget("Role:"+userName,requestUrl);
        if(redisUrl!=null){
            return chain.filter(exchange);
        }
/*       List<LoginRoleVO> loginRoleVOList =  (List<LoginRoleVO>)RedisUtil.get("Role:"+JWTUtil.getUserId(token));
        for (LoginRoleVO loginRoleVO:loginRoleVOList) {
            for (LoginUsersPermissionVO loginUsersPermissionVO:loginRoleVO.getPermissionVOList()) {
                if(regular(requestUrl,loginUsersPermissionVO.getPUrl())){
                    //放行
                    return chain.filter(exchange);
                }
            }
        }*/
        //抛出异常
        return response.writeWith(Flux.just(exception(exchange,"该用户没有访问这个接口的权限")));
    }

    @Override
    public int getOrder() {
        return 100;
    }

    /**
     * 正则判断
     * @param url
     * @param url1
     * @return
     */
    public boolean regular(String url,String url1){
        Pattern p = Pattern.compile(".*" +
                url1 +
                ".*");
        Matcher m = p.matcher(url);
        return m.matches();
    }
    public DataBuffer  exception(ServerWebExchange exchange,String message){
        final ServerHttpResponse response = exchange.getResponse();
        byte[] bytes = ("{\"code\":\"999\",\"message\":\"" +
                message +
                "\",\"bean\":\"null\"}").getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
        return buffer;
    }

}
